﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using Calabonga.Xml.Exports;
using VideoSeller.Business.Data;
using VideoSeller.Business.Data.Entities;

namespace VideoSeller.Business.Models
{
	public class ResourceModel : Repository<CultureResource>
	{
		public IEnumerable<string> GetUniqueCultures()
		{
			return Table.Select(x => x.CultureName).Distinct().OrderBy(x => x);
		}

		public IEnumerable<CultureInfo> GetUniqueCultureInfos()
		{
			var cultures = Table.Select(x => x.CultureName).Distinct().OrderBy(x => x);

			return cultures.Select(x => new CultureInfo(x));
		}

		public IEnumerable<CultureResource> GetResources(string resourceObject)
		{
			return
				Table.Where(
					x => x.ResourceObject.ToLower() == resourceObject.ToLower() && x.CultureName == CultureInfo.CurrentUICulture.Name);
		}

		public List<ResourceItem> GetResourceItems()
		{
			var resourceItems = new List<ResourceItem>();

			foreach (var cultureResource in Table)
			{
				var resItem = resourceItems.SingleOrDefault(x => x.ResourceName == cultureResource.ResourceName && x.ResourceObject == cultureResource.ResourceObject);

				if (resItem != null)
				{
					resItem.Id.Add(cultureResource.Id.ToString());
					resItem.CultureValues.Add(cultureResource.CultureName, cultureResource.ResourceValue);
				}
				else
				{
					var item = new ResourceItem
						{
							Id = new List<string> {cultureResource.Id.ToString()},
							ResourceName = cultureResource.ResourceName,
							ResourceObject = cultureResource.ResourceObject,
							CultureValues = new Dictionary<string, string> {{cultureResource.CultureName, cultureResource.ResourceValue}}
						};
					resourceItems.Add(item);
				}
			}

			return resourceItems;
		}

		public string ExportResources()
		{
			var cultures = GetUniqueCultures().ToList();
			var resourceItems = GetResourceItems();
			var wb = new Workbook();

			wb.Properties.Author = "VideoSeller";
			wb.Properties.Created = DateTime.Today;

			wb.ExcelWorkbook.ActiveSheet = 1;
			wb.ExcelWorkbook.DisplayInkNotes = false;
			wb.ExcelWorkbook.FirstVisibleSheet = 1;
			wb.ExcelWorkbook.ProtectStructure = false;

			var headerStyle = new Style("headerStyle");
			headerStyle.Font = new Font {Bold = true, Size = 14, Color = "#000000"};
			wb.AddStyle(headerStyle);

			var itemStyle = new Style("itemStyle");
			itemStyle.Font = new Font {Bold = false, Size = 13, Color = "#000000"};
			wb.AddStyle(itemStyle);

			var ws = new Worksheet("Лист 1");
			ws.AddCell(0, 0, "Номер", 1, "headerStyle");
			ws.AddCell(0, 1, "Ресурс", 2, "headerStyle");
			ws.AddCell(0, 2, "Объект", 3, "headerStyle");

			for (var i = 0; i < cultures.Count(); i++)
			{
				var culture = new CultureInfo(cultures[i]);
				ws.AddCell(0, i + 3, culture.NativeName, (uint) i + 4, "headerStyle");
			}

			for (var i = 0; i < resourceItems.Count; i++)
			{
				ws.AddCell(i + 1, 0, string.Join("-", resourceItems[i].Id), 1, "itemStyle");
				ws.AddCell(i + 1, 1, resourceItems[i].ResourceName, 2, "itemStyle");
				ws.AddCell(i + 1, 2, resourceItems[i].ResourceObject, 3, "itemStyle");

				for (var j = 0; j < cultures.Count(); j++)
				{
					if (resourceItems[i].CultureValues.ContainsKey(cultures[j]))
					{
						ws.AddCell(i + 1, j + 3, resourceItems[i].CultureValues[cultures[j]], (uint) j + 4, "itemStyle");
					}
					else
					{
						ws.AddCell(i + 1, j + 3, "", (uint) j + 4, "itemStyle");
					}
				}
			}

			wb.AddWorksheet(ws);

			return wb.ExportToXML();
		}

		public void ImportResources(Stream inputStream)
		{
			try
			{
				var xdoc = XDocument.Load(inputStream);

				if (xdoc.Root != null)
				{
					var nodes = xdoc.Descendants(XName.Get("Row", xdoc.Root.Name.NamespaceName)).ToList();
					var cultures = new List<string>();
					var newItems = new List<CultureResource>();

					if (nodes.Any())
					{
						for (var i = 3; i < nodes[0].Elements().Count(); i++)
						{
							var value = nodes[0].Elements().ElementAt(i).Value;
							var culture = CultureInfo.GetCultures(CultureTypes.SpecificCultures).FirstOrDefault(x => x.NativeName == value);

							if (culture != null)
							{
								cultures.Add(culture.Name);
							}
						}

						if (cultures.Any())
						{
							for (var i = 1; i < nodes.Count(); i++)
							{
								for (var j = 0; j < cultures.Count; j++)
								{
									var elements = nodes[i].Elements().ToList();
									var item = new CultureResource
										{
											ResourceName = elements[1].Value,
											ResourceObject = elements[2].Value,
											CultureName = cultures[j],
											ResourceValue = elements.Count > j + 3 ? elements[j + 3].Value : string.Empty
										};
									newItems.Add(item);
								}
							}
						}
					}

					if (newItems.Any())
					{
						Table.DeleteAllOnSubmit(Table);
						SubmitAllChanges();
						Table.InsertAllOnSubmit(newItems);
						SubmitAllChanges();
						HttpContext.Current.Application["ShouldUpdateResourceProviderCache"] = true;
					}

				}
			}
			catch (Exception)
			{
			}
		}
	}
}